#include <iostream>
#include <string>
using namespace std;

struct Data
{
    int year;
    int month;
    int day;
};

class Account
{
protected:
    int number;
    float balance;
    float annualInterestRate;
    const Data createData;
public:
    Account(int number, float annualInterestRate, Data createData) :
        number(number), balance(0), annualInterestRate(annualInterestRate), createData(createData) {}
    float getBalance() const { return this->balance; }
    void deposit(float money) { this->balance+=money; }
    bool withdraw(float money);
    string toString() const
    {
        return "Account Number:"+to_string(number)+" Balance:"+to_string(balance);
    }
};

class checkingAccount : public Account
{
protected:
    float overdraftLimit;
public:
    checkingAccount(int number, float annualInterestRate, Data createData, float overdraftLimit):
        Account(number, annualInterestRate, createData), overdraftLimit(overdraftLimit) {}
    bool withdraw(float money)
    {
        float result=this->balance-money;
        if(result<-overdraftLimit)
            return false;
        else
        {
            this->balance=result;
            return true;
        }
    }
    string toString() const
    {
        string result="Account Number:"+to_string(number)+" Balance:"+to_string(balance)+" Surplus Overdraft Limit:";
        if(this->balance<0)
            result+=to_string(this->overdraftLimit+this->balance);
        else
            result+=to_string(this->overdraftLimit);
        return result;
    }
};

class savingAccount : public Account
{
public:
    savingAccount(int number, float annualInterestRate, Data createData) :
        Account(number, annualInterestRate, createData) {}
    bool withdraw(float money)
    {
        float result=this->balance-money;
        if(result<0)
            return false;
        else
        {
            this->balance=result;
            return true;
        }
    }
};

template<class T>
void save(T &account)
{
    if(account.withdraw(100))
        cout<<"success"<<endl;
    else
        cout<<"fail"<<endl;
}

int main()
{
    savingAccount sa(0001,0.01,Data{2019,11,11});
    checkingAccount ca(0002,0.01,Data{2019,11,11},1000);
    cout<<sa.toString()<<endl;
    save(sa);
    sa.deposit(1000);
    cout<<sa.toString()<<endl;
    save(sa);
    cout<<sa.toString()<<endl;
    cout<<ca.toString()<<endl;
    save(ca);
    cout<<ca.toString()<<endl;
    ca.deposit(1000);
    cout<<ca.toString()<<endl;
}
